using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;

namespace Brjnk.Common
{
    [ContentProperty("Templates")]
    public class GenericTemplateSelector : DataTemplateSelector
    {
        private List<TemplateDefinition> templates = new List<TemplateDefinition>();

        public List<TemplateDefinition> Templates { get { return templates; } set { templates = value; } }

        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            Type type = null;
            if ((object)item != null)
                type = item.GetType();

            foreach (var def in templates)
            {
                if (IsMatching(def, item, type))
                    return def.Template;
            }
            return null;
        }

        private bool IsMatching(TemplateDefinition def, object item, Type type)
        {
            bool retVal;
            if (item == null || def.ObjectType == null)
            {
                if (def.ObjectType == null) retVal = true;
                retVal = false;
            }
            else
            {
                if (def.ObjectType == type) retVal = true;
                else if (def.ObjectType.IsAssignableFrom(type) && def.IncludeInherited) retVal = true;
                else retVal = false;
            }
            return def.Negate ^ retVal;
        }
    }

    [ContentProperty("Template")]
    public class TemplateDefinition
    {
        private bool includeInherited = true;

        public bool IncludeInherited
        {
            get { return includeInherited; }
            set { includeInherited = value; }
        }

        private bool negate;

        public bool Negate
        {
            get { return negate; }
            set { negate = value; }
        }

        public Type ObjectType { get; set; }

        public DataTemplate Template { get; set; }
    }
}